 /// @file ExchangeMaterials.h
 /// @brief ExchangeMaterials 
 /// @createtime 2025-05-29

#ifndef EXCHANGEMATERIALS_H
#define EXCHANGEMATERIALS_H

#include <string>
#include <sstream>
#include <unordered_map>
#include "topology/TopoShape.hpp"

namespace  AMCAX::Exchange 
{

class ExchangeMaterialItem{
    public:
    ExchangeMaterialItem() = default;
    /// @brief Construct a new Exchange Material object using color
    /// 
    /// @param[in] color:  The color information may be represented in hexadecimal format or color names.
    /// @param[out] NONE
    /// @return NONE
    /// @retval NONE
    /// @note NONE
    /// @see NONE
    ExchangeMaterialItem(std::string color):color_(color){} ;
    /// @brief Get the Color object
    /// 
    /// @param[in] NONE
    /// @param[out] Color information
    /// @return Maybe hexadecimal format or color names.
    /// @retval NONE
    /// @note NONE
    /// @see NONE
    std::string GetColor() {
        return color_ ;
    } ;
public:
    /// The name of the material
    std::string name ;
    /// The color of the material such as  #335577 or red
    std::string color_ ; 
    /// The texture information , which may be a URL of an image or a base64 string.
    std::string texture ;
    /// The information of the ambient light ,which may be represented in hexadecimal format or other ways. such as #ffffff
    std::string ambient ; 
    /// The information of the diffuse light ,which may be represented in hexadecimal format or other ways. such as #ffffff
    std::string diffuse ; 
    /// The information of the emissive light ,which may be represented in hexadecimal format or other ways. such as #ffffff
    std::string emissive ;
    /// The information of the specular light ,which may be represented in hexadecimal format or other ways. such as #ffffff
    std::string specular ; 
    /// The shininess of the ambient light information
    double shininess ; 
    /// The transparency of the material ,which is a value between 0.0 and 1.0.
    double transparency ; 

public:
    /// @brief The split representation of RGBA
    /// 
    /// @param[in] rgba: The input hexadecimal RGBA string
    /// @param[out] rgb: The output RGB string
    /// @param[out] op: The output opacity value
    /// @return NONE
    /// @retval NONE
    /// @note NONE
    /// @see NONE
    static void SplitRgba(const std::string& rgba, std::string& rgb, double& op)
    {
        if (rgba.size() != 9) {
            rgb = rgba;
            op = 0.;
            return;
        }

        rgb = rgba.substr(0, 7);

        unsigned int tp;
        std::stringstream ss;
        ss << std::hex << rgba.substr(7);
        ss >> tp;
        op = tp / 255.0f;
    }
} ;

class ExchangeMaterials{

public:
    void AddMaterial(const AMCAX::TopoShape & topoShape, const ExchangeMaterialItem &item){
        materials_.emplace(topoShape,item) ;
    } ;
    bool IsEmpty(){
        return materials_.empty() ;
    }

    std::unordered_map<AMCAX::TopoShape,ExchangeMaterialItem> GetMaterials() const {
        return materials_ ;
    }
private: 
    std::unordered_map<AMCAX::TopoShape,ExchangeMaterialItem> materials_  ;
    
} ;

}

#endif